import { Injectable } from '@nestjs/common';
import { UserService } from '../user/user.service';
import { CacheService } from '../cache/cache.service';
import { JwtService } from '@nestjs/jwt';
import { UserLoginDto } from 'src/user/dto/user-login.dto';
import { ConfigService } from '@nestjs/config';
import { sign } from 'jsonwebtoken';
import * as bcrypt from 'bcryptjs';

@Injectable()
export class AuthService {
  constructor(
    private readonly userService: UserService,
    private readonly jwtService: JwtService,
    private readonly cacheService: CacheService,
    private readonly configService: ConfigService,
  ) {}

  async validateUser(username: string, pass: string): Promise<any> {
    const user = await this.userService.findOne(username);
    if (user && bcrypt.compareSync(pass, user.dataValues.password)) {
      delete user.dataValues.password;
      return user.dataValues;
    }
  }

  async login(user: UserLoginDto) {
    const { username, password, nuid, code } = user;
    const payload = await this.validateUser(username, password);
    const tokenExpire = this.configService.get('token_expire');
    const jwt = this.configService.get('jwt');
    if (payload) {
      const accessToken = sign(payload, jwt.secret, {
        expiresIn: +tokenExpire.access_token_expire,
      });
      const refreshToken = sign(
        { type: 'refresh', id: payload.id },
        jwt.secret,
        {
          expiresIn: +tokenExpire.refresh_token_expire,
        },
      );
      if (nuid === undefined) {
        await this.cacheService.set(
          `access_token_${payload.id}`,
          accessToken,
          +tokenExpire.access_token_expire,
        );
        await this.cacheService.set(
          `refresh_token_${payload.id}`,
          refreshToken,
          +tokenExpire.refresh_token_expire,
        );
        return {
          data: {
            accessToken,
            refreshToken,
            exp: ~~(
              (Date.now() + +tokenExpire.access_token_expire * 1000) /
              1000
            ),
            user: payload,
          },
        };
      } else {
        const cacheCode = await this.cacheService.get(`img_code_${nuid}`);
        if (code === cacheCode) {
          await this.cacheService.set(
            `access_token_${payload.id}`,
            accessToken,
            +tokenExpire.access_token_expire,
          );
          await this.cacheService.set(
            `refresh_token_${payload.id}`,
            refreshToken,
            +tokenExpire.refresh_token_expire,
          );
          return {
            data: {
              accessToken,
              refreshToken,
              exp: ~~(
                (Date.now() + +tokenExpire.access_token_expire * 1000) /
                1000
              ),
              user: payload,
            },
          };
        } else {
          return {
            data: null,
            msg: '验证码错误',
            code: 1,
          };
        }
      }
    } else {
      return {
        data: null,
        msg: '用户不存在或密码错误',
        code: 1,
      };
    }
  }
}
